﻿#region licence
//  Copyright 2008 Michael Cromwell

//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at

//       http://www.apache.org/licenses/LICENSE-2.0

//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Rhino.Mocks;
using log4net.Appender;
using NUnit.Framework.SyntaxHelpers;
using log4net.Core;

namespace log4net.altconf.Tests
{
    
    public class Log4NetDslConfigurationAPI
    {
        protected TestLog4NetDslConfiguration createSUT()
        {
            return new TestLog4NetDslConfiguration();
        }
    }
    
    [TestFixture]
    public class When_dsl_includes_appenders : Log4NetDslConfigurationAPI
    {

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void Given_appender_does_not_implement_interface_should_throw()
        {
            var sut = createSUT();
            sut.AddAppender("foo", typeof(Object));
        }


        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void Given_name_supplied_is_null_should_throw()
        {
            var sut = new TestLog4NetDslConfiguration();
            sut.AddAppender(null, typeof(ConsoleAppender));
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void Given_name_supplied_is_empty_should_throw()
        {
            var sut = createSUT();
            sut.AddAppender("", typeof(ConsoleAppender));
        }


        [Test]
        public void Should_set_name_of_appender_to_passed_name()
        {
            var sut = createSUT();
            sut.AddAppender("foo", typeof(ConsoleAppender));
            var appender = sut.GetAppender("foo");
            Assert.That(appender.Name, Is.EqualTo("foo"));
        }
                       
    }


    [TestFixture]
    public class When_dsl_includes_environment_variable : Log4NetDslConfigurationAPI
    {

        [Test]
        public void Should_return_environment_variable()
        {
            Environment.SetEnvironmentVariable("foo", "foobar");
            var sut = createSUT();
            var value = sut.EnvironmentVariable("foo");
            Assert.That(value, Is.EqualTo("foobar"));
        }
    }

    [TestFixture]
    public class When_dsl_includes_log_for : Log4NetDslConfigurationAPI
    {

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void Given_name_is_null_should_throw()
        {
            var sut = createSUT();
            sut.LogFor(null, () => { });
        }
        
        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void Given_name_is_empty_should_throw()
        {
            var sut = createSUT();
            sut.LogFor("", () => { });
        }


        [Test]
        public void Should_set_current_log()
        {
            var sut = createSUT();
            sut.LogFor("foo", () => { });
            Assert.That(sut.CurrentLog, Is.Not.Null);
            Assert.That(sut.CurrentLog.Name, Is.EqualTo("foo"));
        }


        [Test]
        public void Should_add_current_log_to_list_of_logs()
        {
            var sut = createSUT();
            sut.LogFor("foo", () => { });
            Assert.That(sut.Logs.Count, Is.EqualTo(1));
            Assert.That(sut.Logs[0].Name, Is.EqualTo("foo"));
        }

        [Test]
        public void Should_call_action_passed()
        {
            var called = false;
            var sut = createSUT();
            sut.LogFor("foo", () => called = true);
            Assert.That(called, Is.True);
        }
    }


    [TestFixture]
    public class When_dsl_includes_use_appenders : Log4NetDslConfigurationAPI
    {
        [Test]
        [ExpectedException(typeof(AppenderNotFoundException))]
        public void Given_appender_passed_has_not_been_added_should_throw()
        {
            var sut = createSUT();
            sut.LogFor("foo", () => { });
            sut.UseAppenders(new string[] { "foo" });
        }
        
        [Test]
        [ExpectedException(typeof(NoCurrentLogException))]
        public void Given_current_log_is_null_should_throw()
        {
            var sut = createSUT();
            sut.AddAppender("foo", typeof(ConsoleAppender));
            sut.UseAppenders(new string[] { "foo" });
        }
        
        [Test]
        public void Should_add_appender_to_current_log()
        {
            var sut = createSUT();
            sut.LogFor("foo", () => { });
            sut.AddAppender("foo", typeof(ConsoleAppender));
            sut.UseAppenders(new string[] { "foo" });
            Assert.That(sut.CurrentLog.Appenders.Count, Is.EqualTo(1));
            Assert.That(sut.CurrentLog.Appenders[0].Name, Is.EqualTo("foo"));
        }
    }


    [TestFixture]
    public class When_dsl_includes_ignore_inherited_appenders : Log4NetDslConfigurationAPI
    {
        [Test]
        public void Should_foo_set_additivity_on_current_log()
        {
            var sut = createSUT();
            sut.LogFor("foo", () => { });
            sut.IgnoreInheritedAppenders();
            Assert.That(sut.CurrentLog.Additivity, Is.True);
        }

        [Test]
        [ExpectedException(typeof(NoCurrentLogException))]
        public void Given_no_current_log_is_null_should_throw()
        {
            var sut = createSUT();
            sut.IgnoreInheritedAppenders();
        }
    }

    [TestFixture]
    public class When_dsl_includes_at_level : Log4NetDslConfigurationAPI
    {

        [Test]
        public void Should_set_level_on_current_log()
        {
            var sut = createSUT();
            sut.LogFor("foo", () => { });
            sut.AtLevel(Level.Fatal);
            Assert.That(sut.CurrentLog.Level, Is.EqualTo(Level.Fatal));
        }


        [Test]
        [ExpectedException(typeof(NoCurrentLogException))]
        public void Given_no_current_log_is_null_should_throw()
        {
            var sut = createSUT();
            sut.AtLevel(Level.Fatal);
        }
    }
}
